﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CarCrash.Application.Drawing.entities;
using System.Drawing;
using System.Windows.Forms;
using CarCrash.Core.Services;

namespace CarCrash.Application.Drawing
{

    // контроллер для рисования
    public class Controller
    {

        private readonly List<DrawableEntity> model = new List<DrawableEntity>();
        // выбранный пользователем элемент, который уже нарисован, на котором нарисуется выделение
        private DrawableEntity selectedEntity;
        // сущность, которая была выбрана в ObjectDialog. Обнуляю после 1 запроса на получение
        private DrawableEntity chosenEntity;
        public DrawableEntity ChosenEntity {
            get { var entity = chosenEntity; chosenEntity = null; return entity; }
            set { chosenEntity = value; }
        }
        private Pen selectionPen;

        public void RepaintAll(Graphics g)
        {
            foreach (var entity in model)
            {
                entity.Paint(g);
            }
            PaintSelection(g);
        }

        public void Add(DrawableEntity entity)
        {
            model.Add(entity);
        }

        // выделяет элемент, если он полностью попал в прямоугольник
        // множественное выделение не поддерживается
        public void SetSelection(int x, int y, int endX, int endY)
        {
            if (x > endX) { int buf = x; x = endX; endX = buf; }
            if (y > endY) { int buf = y; y = endY; endY = buf; }
            foreach (var entity in model)
            {
                if (entity.CorrectBeginX > x && entity.CorrectBeginY > y 
                    && entity.CorrectEndX < endX && entity.CorrectEndY < endY)
                {
                    selectedEntity = entity;
                    break;
                }
            }
        }

        // снимает выделение с выделенного ранее элемента, если точка не лежит в нем
        public void DropSelection(int x, int y)
        {
            if (!OnSelectedEntityClick(x, y))
                selectedEntity = null;
        }

        // рисует рамку вокруг выбранного элемента
        private void PaintSelection(Graphics g)
        {
            if (selectedEntity == null) return;
            int x = selectedEntity.CorrectBeginX - 1; int y = selectedEntity.CorrectBeginY - 1;
            int endX = selectedEntity.CorrectEndX + 1; int endY = selectedEntity.CorrectEndY + 1;
            g.DrawRectangle(selectionPen, x, y, endX - x, endY - y);
        }

        // рисует прямоугольник выделения
        public void PaintSelectionBox(Graphics g, int x, int y, int endX, int endY)
        {
            g.DrawLine(selectionPen, x, y, endX, y);
            g.DrawLine(selectionPen, endX, endY, endX, y);
            g.DrawLine(selectionPen, endX, endY, x, endY);
            g.DrawLine(selectionPen, x, y, x, endY);
        }

        // открывает окно с настройками выделенного элемента
        public void OpenSelectedEntityPropertyWindow(int x, int y, Control owner)
        {
            if (OnSelectedEntityClick(x, y))
                selectedEntity.GetForm().ShowDialog(owner);
        }

        public void DragSelectedEntityTo(int fromX, int fromY, int toX, int toY)
        {
            selectedEntity.BeginX = selectedEntity.BeginX - (fromX - toX);
            selectedEntity.BeginY = selectedEntity.BeginY - (fromY - toY);
            selectedEntity.EndX = selectedEntity.EndX - (fromX - toX);
            selectedEntity.EndY = selectedEntity.EndY - (fromY - toY);
        }

        public bool OnSelectedEntityClick(int x, int y)
        {
            if (selectedEntity == null) return false;
            if (selectedEntity.CorrectBeginX < x && selectedEntity.CorrectEndX > x
                && selectedEntity.CorrectBeginY < y && selectedEntity.CorrectEndY > y)
                return true;
            return false;
        }

        private Controller()
        {
            selectionPen = new Pen(Color.BlueViolet, 1);
            selectionPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
        }
        private static Controller instance;
        public static Controller Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Controller();
                }
                return instance;
            }
        }

    }

}